﻿using Digitalmes.Core.Common.SerialPorts;

namespace Digitalmes.Infrastructure.IO.SerialPorts;

/// <summary>
/// 串口开关。
/// </summary>
/// <param name="manager"></param>
internal sealed class SerialPortsSwitch(ISerialPortsManager manager) : ISerialPortsSwitch
{
    public (bool ok, string? portName, Exception? ex) Open()
    {
        var serialPort = manager.SerialPorts.FirstOrDefault();
        if (serialPort == null)
        {
            return (false, default, new NotFoundSerialPortException());
        }

        try
        {
            serialPort.Open();

            return (true, serialPort.PortName, default);
        }
        catch (Exception ex)
        {
            return (false, serialPort.PortName, ex);
        }
    }

    public (bool ok, Exception? ex) Open(string portName)
    {
        var serialPort = manager.SerialPorts.SingleOrDefault(s => s.PortName == portName);
        if (serialPort == null)
        {
            return (false, new NotFoundSerialPortException());
        }

        try
        {
            serialPort.Open();

            return (true, default);
        }
        catch (Exception ex)
        {
            return (false, ex);
        }
    }

    public (bool ok, Exception? ex) OpenViaPurpose(string purpose)
    {
        var serialPort = manager.SerialPorts.SingleOrDefault(s => s.Purpose == purpose);
        if (serialPort == null)
        {
            return (false, new NotFoundSerialPortException());
        }

        try
        {
            serialPort.Open();

            return (true, default);
        }
        catch (Exception ex)
        {
            return (false, ex);
        }
    }

    public (bool ok, Exception? ex) Close()
    {
        var serialPort = manager.SerialPorts.FirstOrDefault();
        if (serialPort == null)
        {
            return (false, new NotFoundSerialPortException());
        }

        try
        {
            serialPort.Close();

            return (true, default);
        }
        catch (Exception ex)
        {
            return (false, ex);
        }
    }

    public (bool ok, Exception? ex) Close(string portName)
    {
        var serialPort = manager.SerialPorts.SingleOrDefault(s => s.PortName == portName);
        if (serialPort == null)
        {
            return (false, new NotFoundSerialPortException());
        }

        try
        {
            serialPort.Close();

            return (true, default);
        }
        catch (Exception ex)
        {
            return (false, ex);
        }
    }

    public (bool ok, Exception? ex) CloseViaPurpose(string purpose)
    {
        var serialPort = manager.SerialPorts.SingleOrDefault(s => s.Purpose == purpose);
        if (serialPort == null)
        {
            return (false, new NotFoundSerialPortException());
        }

        try
        {
            serialPort.Close();

            return (true, default);
        }
        catch (Exception ex)
        {
            return (false, ex);
        }
    }
}
